import React, { useState, useEffect } from 'react';
import {
  Card,
  Form,
  Input,
  Select,
  Button,
  Steps,
  Row,
  Col,
  Upload,
  message,
  Tabs,
  Space,
  Spin,
  Alert,
  Collapse,
  Tag,
  Progress,
  Table,
  Divider
} from 'antd';
import {
  UploadOutlined,
  ExperimentOutlined,
  LineChartOutlined,
  BarChartOutlined,
  ScatterChartOutlined
} from '@ant-design/icons';
import ReactECharts from 'echarts-for-react';
import { analyticsAPI } from '../services/api';

const { Step } = Steps;
const { TabPane } = Tabs;
const { Panel } = Collapse;
const { Option } = Select;
const { TextArea } = Input;

interface Job {
  id: string;
  type: string;
  status: string;
  created_at: string;
  completed_at?: string;
  input_dataset_id: string;
  parameters: any;
}

const Analytics: React.FC = () => {
  const [form] = Form.useForm();
  const [datasets, setDatasets] = useState([]);
  const [currentStep, setCurrentStep] = useState(0);
  const [jobType, setJobType] = useState('');
  const [selectedDataset, setSelectedDataset] = useState('');
  const [jobParameters, setJobParameters] = useState({});
  const [currentJob, setCurrentJob] = useState<Job | null>(null);
  const [jobResults, setJobResults] = useState(null);
  const [loading, setLoading] = useState(false);
  const [jobs, setJobs] = useState([]);

  useEffect(() => {
    fetchDatasets();
    fetchJobs();
    const interval = setInterval(fetchJobs, 10000); // Refresh jobs every 10 seconds
    return () => clearInterval(interval);
  }, []);

  const fetchDatasets = async () => {
    try {
      const data = await analyticsAPI.getDatasets();
      setDatasets(data);
    } catch (error) {
      message.error('Failed to fetch datasets');
    }
  };

  const fetchJobs = async () => {
    try {
      const data = await analyticsAPI.getJobs();
      setJobs(data);
    } catch (error) {
      console.error('Failed to fetch jobs:', error);
    }
  };

  const handleJobTypeChange = (value: string) => {
    setJobType(value);
    setCurrentStep(1);
  };

  const handleDatasetChange = (value: string) => {
    setSelectedDataset(value);
    setCurrentStep(2);
  };

  const handleParametersChange = (values: any) => {
    setJobParameters(values);
    setCurrentStep(3);
  };

  const submitJob = async () => {
    if (!jobType || !selectedDataset) {
      message.error('Please select job type and dataset');
      return;
    }

    setLoading(true);
    try {
      const jobData = {
        job_type: jobType,
        input_dataset_id: selectedDataset,
        parameters: jobParameters
      };

      const job = await analyticsAPI.submitJob(jobData);
      setCurrentJob(job);
      message.success('Job submitted successfully');

      // Start polling for job status
      pollJobStatus(job.id);
    } catch (error) {
      message.error('Failed to submit job');
    }
    setLoading(false);
  };

  const pollJobStatus = async (jobId: string) => {
    const checkStatus = async () => {
      try {
        const job = await analyticsAPI.getJob(jobId);
        setCurrentJob(job);

        if (job.status === 'completed') {
          const results = await analyticsAPI.getJobResult(jobId);
          setJobResults(results);
          setCurrentStep(4); // Results step
          return; // Stop polling
        }

        if (job.status === 'failed') {
          message.error(`Job failed: ${job.error_message}`);
          return; // Stop polling
        }

        // Continue polling
        setTimeout(checkStatus, 2000);
      } catch (error) {
        console.error('Error polling job status:', error);
      }
    };

    checkStatus();
  };

  const renderJobForm = () => {
    switch (jobType) {
      case 'kmeans':
        return (
          <Form
            form={form}
            layout="vertical"
            onFinish={handleParametersChange}
          >
            <Form.Item label="Number of Clusters (K)" name="k" initialValue={3}>
              <Input type="number" min={2} max={20} />
            </Form.Item>
            <Form.Item label="Maximum Iterations" name="max_iter" initialValue={100}>
              <Input type="number" min={10} max={1000} />
            </Form.Item>
            <Form.Item label="Random Seed" name="seed" initialValue={42}>
              <Input type="number" />
            </Form.Item>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Set Parameters
              </Button>
            </Form.Item>
          </Form>
        );

      case 'pca':
        return (
          <Form
            form={form}
            layout="vertical"
            onFinish={handleParametersChange}
          >
            <Form.Item label="Number of Components" name="k" initialValue={10}>
              <Input type="number" min={2} max={100} />
            </Form.Item>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Set Parameters
              </Button>
            </Form.Item>
          </Form>
        );

      case 'similarity':
        return (
          <Form
            form={form}
            layout="vertical"
            onFinish={handleParametersChange}
          >
            <Form.Item label="Similarity Metric" name="metric" initialValue="cosine">
              <Select>
                <Option value="cosine">Cosine</Option>
                <Option value="euclidean">Euclidean</Option>
                <Option value="manhattan">Manhattan</Option>
              </Select>
            </Form.Item>
            <Form.Item label="Threshold" name="threshold">
              <Input type="number" step="0.1" min={0} max={1} />
            </Form.Item>
            <Form.Item label="Sample Size" name="sample_size" initialValue={1000}>
              <Input type="number" min={100} max={10000} />
            </Form.Item>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Set Parameters
              </Button>
            </Form.Item>
          </Form>
        );

      case 'outlier_detection':
        return (
          <Form
            form={form}
            layout="vertical"
            onFinish={handleParametersChange}
          >
            <Form.Item label="Method" name="method" initialValue="distance">
              <Select>
                <Option value="distance">Distance-based</Option>
                <Option value="density">Density-based</Option>
              </Select>
            </Form.Item>
            <Form.Item label="Threshold" name="threshold" initialValue={2.0}>
              <Input type="number" step="0.1" min={0.1} max={5.0} />
            </Form.Item>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Set Parameters
              </Button>
            </Form.Item>
          </Form>
        );

      case 'statistics':
        return (
          <Form onFinish={handleParametersChange}>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Analyze Statistics
              </Button>
            </Form.Item>
          </Form>
        );

      default:
        return <div>Select a job type to configure parameters</div>;
    }
  };

  const renderResults = () => {
    if (!jobResults) return null;

    switch (jobResults.type) {
      case 'kmeans':
        return <KMeansResults results={jobResults} />;
      case 'pca':
        return <PCAResults results={jobResults} />;
      case 'statistics':
        return <StatisticsResults results={jobResults} />;
      case 'similarity':
        return <SimilarityResults results={jobResults} />;
      case 'outlier_detection':
        return <OutlierResults results={jobResults} />;
      case 'nearest_neighbors':
        return <NearestNeighborsResults results={jobResults} />;
      default:
        return <pre>{JSON.stringify(jobResults, null, 2)}</pre>;
    }
  };

  return (
    <div>
      <Row gutter={[16, 16]}>
        <Col xs={24} lg={16}>
          <Card title="Analytics Workflow">
            <Steps current={currentStep} style={{ marginBottom: 24 }}>
              <Step title="Select Job Type" icon={<ExperimentOutlined />} />
              <Step title="Choose Dataset" icon={<UploadOutlined />} />
              <Step title="Set Parameters" icon={<LineChartOutlined />} />
              <Step title="Submit Job" icon={<BarChartOutlined />} />
              <Step title="View Results" icon={<ScatterChartOutlined />} />
            </Steps>

            {currentStep === 0 && (
              <div>
                <h3>Select Job Type</h3>
                <Space direction="vertical" style={{ width: '100%' }}>
                  <Button
                    block
                    onClick={() => handleJobTypeChange('kmeans')}
                  >
                    K-Means Clustering
                  </Button>
                  <Button
                    block
                    onClick={() => handleJobTypeChange('pca')}
                  >
                    PCA Dimensionality Reduction
                  </Button>
                  <Button
                    block
                    onClick={() => handleJobTypeChange('similarity')}
                  >
                    Similarity Analysis
                  </Button>
                  <Button
                    block
                    onClick={() => handleJobTypeChange('outlier_detection')}
                  >
                    Outlier Detection
                  </Button>
                  <Button
                    block
                    onClick={() => handleJobTypeChange('statistics')}
                  >
                    Vector Statistics
                  </Button>
                </Space>
              </div>
            )}

            {currentStep === 1 && (
              <div>
                <h3>Choose Dataset</h3>
                <Select
                  style={{ width: '100%', marginBottom: 16 }}
                  placeholder="Select a dataset"
                  onChange={handleDatasetChange}
                >
                  {datasets.map((dataset: any) => (
                    <Option key={dataset.id} value={dataset.id}>
                      {dataset.name} ({dataset.shape?.n_samples} samples, {dataset.shape?.n_dimensions} dimensions)
                    </Option>
                  ))}
                </Select>
              </div>
            )}

            {currentStep === 2 && (
              <div>
                <h3>Set Parameters</h3>
                {renderJobForm()}
              </div>
            )}

            {currentStep === 3 && (
              <div>
                <h3>Submit Job</h3>
                <Button
                  type="primary"
                  size="large"
                  onClick={submitJob}
                  loading={loading}
                >
                  Submit Job
                </Button>
                {currentJob && (
                  <div style={{ marginTop: 16 }}>
                    <p>Job ID: {currentJob.id}</p>
                    <p>Status: <Tag color="blue">{currentJob.status}</Tag></p>
                  </div>
                )}
              </div>
            )}

            {currentStep === 4 && jobResults && (
              <div>
                <h3>Results</h3>
                {renderResults()}
              </div>
            )}
          </Card>
        </Col>

        <Col xs={24} lg={8}>
          <Card title="Recent Jobs">
            <Table
              dataSource={jobs.slice(0, 10)}
              pagination={false}
              columns={[
                {
                  title: 'Type',
                  dataIndex: 'type',
                  key: 'type',
                },
                {
                  title: 'Status',
                  dataIndex: 'status',
                  key: 'status',
                  render: (status) => (
                    <Tag color={
                      status === 'completed' ? 'green' :
                      status === 'running' ? 'blue' :
                      status === 'failed' ? 'red' : 'default'
                    }>
                      {status}
                    </Tag>
                  )
                },
                {
                  title: 'Created',
                  dataIndex: 'created_at',
                  key: 'created_at',
                  render: (date) => new Date(date).toLocaleString()
                }
              ]}
              rowKey="id"
            />
          </Card>
        </Col>
      </Row>
    </div>
  );
};

// Result components for different job types
const KMeansResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>K-Means Clustering Results</h4>
    <Row gutter={[16, 16]}>
      <Col span={12}>
        <Card title="Cluster Information">
          <p>Number of clusters: {results.result.n_clusters}</p>
          <p>Silhouette score: {results.result.silhouette_score.toFixed(3)}</p>
        </Card>
      </Col>
      <Col span={12}>
        <Card title="Cluster Distribution">
          <ReactECharts
            option={{
              title: { text: 'Cluster Sizes' },
              tooltip: { trigger: 'axis' },
              xAxis: { type: 'category', data: results.result.cluster_counts.map((c: any) => `Cluster ${c.cluster}`) },
              yAxis: { type: 'value' },
              series: [{
                type: 'bar',
                data: results.result.cluster_counts.map((c: any) => c.count)
              }]
            }}
            style={{ height: '250px' }}
          />
        </Card>
      </Col>
    </Row>
  </div>
);

const PCAResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>PCA Results</h4>
    <Card title="Dimensionality Reduction Summary">
      <p>Original dimensions: {results.result.original_dimensions}</p>
      <p>Reduced to: {results.result.n_components} components</p>
      <p>Total explained variance: {results.result.explained_variance.reduce((a: number, b: number) => a + b, 0).toFixed(3)}</p>
    </Card>
  </div>
);

const StatisticsResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>Vector Statistics</h4>
    <Row gutter={[16, 16]}>
      <Col span={8}>
        <Card title="Dataset Overview">
          <p>Number of samples: {results.result.n_samples}</p>
          <p>Vector dimensions: {results.result.vector_size}</p>
        </Card>
      </Col>
      <Col span={8}>
        <Card title="Vector Norm Statistics">
          <p>Mean: {results.result.norm_statistics.mean.toFixed(3)}</p>
          <p>Std: {results.result.norm_statistics.std.toFixed(3)}</p>
          <p>Min: {results.result.norm_statistics.min.toFixed(3)}</p>
          <p>Max: {results.result.norm_statistics.max.toFixed(3)}</p>
        </Card>
      </Col>
      <Col span={8}>
        <Card title="Dimension Statistics">
          <p>Dimensions: {results.result.vector_size}</p>
        </Card>
      </Col>
    </Row>
  </div>
);

const SimilarityResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>Similarity Analysis Results</h4>
    <Card title="Analysis Summary">
      <p>Metric: {results.result.metric}</p>
      <p>Number of pairs analyzed: {results.result.n_pairs}</p>
      <p>Sample size: {results.parameters.sample_size}</p>
    </Card>
  </div>
);

const OutlierResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>Outlier Detection Results</h4>
    <Row gutter={[16, 16]}>
      <Col span={12}>
        <Card title="Detection Summary">
          <p>Method: {results.result.method}</p>
          <p>Threshold: {results.parameters.threshold}</p>
        </Card>
      </Col>
      <Col span={12}>
        <Card title="Outlier Counts">
          <ReactECharts
            option={{
              title: { text: 'Outlier Distribution' },
              tooltip: { trigger: 'item' },
              legend: { orient: 'vertical', left: 'left' },
              series: [{
                type: 'pie',
                radius: '50%',
                data: results.result.outlier_counts.map((c: any) => ({
                  value: c.count,
                  name: c.is_outlier ? 'Outliers' : 'Normal'
                }))
              }]
            }}
            style={{ height: '250px' }}
          />
        </Card>
      </Col>
    </Row>
  </div>
);

const NearestNeighborsResults: React.FC<{ results: any }> = ({ results }) => (
  <div>
    <h4>Nearest Neighbors Results</h4>
    <Card title="Search Results">
      <p>K: {results.result.k}</p>
      <p>Metric: {results.result.metric}</p>
      <p>Query vector dimension: {results.parameters.query_vector.length}</p>
    </Card>
  </div>
);

export default Analytics;